package com.framework.config;

import com.framework.common.config.RedisConfig;
import com.framework.common.config.SensitiveWordsInit;
import com.framework.common.config.SystemConfigName;
import com.framework.common.utils.SpringContextUtils;
import com.framework.modules.sys.entity.SysConfigEntity;
import com.framework.modules.sys.redis.SysConfigRedis;
import com.framework.modules.sys.service.SysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.StandardServletEnvironment;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;


@Component
@Configuration
public class DatabaseInitConfig {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ConfigurableEnvironment environment;

    @Autowired
    private SysConfigService service;

    @Autowired
    private SysConfigRedis sysConfigRedis;

    private Boolean isReload = false;

    public DatabaseInitConfig() {

    }

    public DatabaseInitConfig(Boolean reload) {
        this.isReload = reload;
    }

    @PostConstruct
    public void init() {

        logger.info("正在加载数据库配置( %s )...............".format(this.isReload ? "重新载入" : "初始化"));

        // 获取系统属性集合
        MutablePropertySources propertySources = null;

        if(!this.isReload){
            propertySources = environment.getPropertySources();
        }
        else {
            propertySources = ((StandardServletEnvironment) SpringContextUtils.applicationContext.getEnvironment()).getPropertySources();
        }

        try {
            Map<String, Object> filter = new HashMap<>();
            filter.put("1", "1");

            // 从数据库获取自定义变量列表
            List<SysConfigEntity> configlist = service.selectByMap(filter);

            logger.info(String.format("========================== 找到 %s 项配置 ==========================", configlist.size()));

            Map<String, String> settings = new HashMap<>();
            configlist.forEach(entity -> {
                String key = String.format("sys.%s", entity.getParamKey());
                String value = entity.getParamValue();
                settings.put(key, entity.getParamValue());

                sysConfigRedis.saveOrUpdate(entity);

                if(SystemConfigName.TEXT_BAD_WORDS.equals(key)){
                    //初始化敏感词
                    SensitiveWordsInit.initSensitiveWords(entity.getParamValue());

                }else{
                    logger.info(String.format("[ %s ] = %s", key, value.split("\\n").length > 1 ? "..." : value));
                }

            });

            // 将转换后的列表加入属性中
            Properties properties = new Properties();
            properties.putAll(settings);


            // 将属性转换为属性集合，并指定名称
            PropertiesPropertySource constants = new PropertiesPropertySource("sys-db-config", properties);

            // 定义寻找属性的正则，该正则为系统默认属性集合的前缀
            Pattern p = compile("^applicationConfig.*");

            // 接收系统默认属性集合的名称
            String applicationConfigName = null;
            // 标识是否找到系统默认属性集合
            boolean flag = false;
            // 遍历属性集合
            for (PropertySource<?> source : propertySources) {
                logger.info(String.format("检查配置文件 %s ", source.getName()));
                // 正则匹配  匹配到：OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}
                if (p.matcher(source.getName()).matches()) {
                    // 接收名称
                    applicationConfigName = source.getName();
                    // 变更标识
                    flag = true;

                    break;
                }
            }

            if (flag) {
                //废弃：如果找到该配置文件,找到则将自定义属性添加到该属性之后，意思就是以application.properties文件配置为准  如果想要以数据库配置为准，就修改为 propertySources.addBefore(name, constants)
                //propertySources.addAfter(applicationConfigName, constants);
                logger.info(String.format("将参数值附加到配置文件 %s ", applicationConfigName));
                //20201214　修改
                propertySources.replace(applicationConfigName, constants);
            } else {
                propertySources.addFirst(constants);
            }
        } catch (Exception e) {
            logger.info(String.format("========================== init database config error : %s ==========================", e.getMessage()));
        }

    }

    /**
     * 重载配置文件
     */
    public static void reloadConfig() {
        String name = DatabaseInitConfig.class.getSimpleName();
        name = name.substring(0,1).toLowerCase() + name.substring(1);
        DatabaseInitConfig clazz = SpringContextUtils.getBean(name, DatabaseInitConfig.class);
        clazz.isReload = true;
        clazz.init();
    }

}
